package com.ntschy.bt.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ntschy.bt.entity.dataobject.BtQuestion;
import com.ntschy.bt.entity.dataobject.BtQuestionAnswer;
import com.ntschy.bt.entity.dataobject.BtQuestionInfo;
import com.ntschy.bt.entity.dataobject.BtQuestionOption;
import com.ntschy.bt.entity.dto.BtQuestionAnswerDTO;
import com.ntschy.bt.entity.dto.BtQuestionDTO;
import com.ntschy.bt.entity.dto.BtQuestionInfoDTO;
import com.ntschy.bt.entity.dto.BtQuestionPageDTO;
import com.ntschy.bt.entity.mapstruct.BtQuestionMapstruct;
import com.ntschy.bt.mapper.BtQuestionAnswerMapper;
import com.ntschy.bt.mapper.BtQuestionInfoMapper;
import com.ntschy.bt.mapper.BtQuestionMapper;
import com.ntschy.bt.mapper.BtQuestionOptionMapper;
import com.ntschy.bt.service.IBtQuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 问卷调查 服务实现类
 * </p>
 *
 * @author cm
 * @since 2020-12-28
 */
@Service
public class BtQuestionServiceImpl implements IBtQuestionService {

    @Autowired
    private BtQuestionMapper questionMapper;

    @Autowired
    private BtQuestionInfoMapper questionInfoMapper;

    @Autowired
    private BtQuestionOptionMapper questionOptionMapper;

    @Autowired
    private BtQuestionAnswerMapper questionAnswerMapper;

    // mapstruct 转化接口类
    @Autowired
    private BtQuestionMapstruct questionMapstruct;

    // * ================================================基础增删改查BEGIN============================================= *

    /**
     * 分页查询调查问卷
     * 当前查询条件：
     * @param questionPageDTO 分页 DTO
     * @return 问卷调查列表
     */
    @Override
    public PageInfo<BtQuestion> pageQuestion(BtQuestionPageDTO questionPageDTO) {
        //开启分页配置：
        PageHelper.startPage(questionPageDTO.getCurrent(),10);
        questionPageDTO.setDelFlag(0);

        //* 对象转换
        BtQuestion question = questionMapstruct.questionMapStruct(questionPageDTO);

        List<BtQuestion> userList = questionMapper.pageQuestion(question);
        PageInfo pageInfo = PageInfo.of(userList);

        return pageInfo;
    }

    /**
     * 新增问卷
     * @param
     * @return 新增结果
     */
    @Transactional
    @Override
    public int addSaveSaveQuestion(BtQuestionDTO questionDTO) {

        //* 执行对象转换：
        BtQuestion question = questionMapstruct.questionMapStruct(questionDTO);
        //! 插入 问卷调查 主表
        int isInsertQuestionSuccess = questionMapper.insert(question);

        // 把 infoDTO 集合转为 info 集合
        List<BtQuestionInfo> questionInfos = new ArrayList<>();
        // 创建 option 集合
        List<BtQuestionOption> questionOptions = new ArrayList<>();

        questionDTO.getQuestions().forEach((item) ->{
            //* 入问卷调查 内容表
            BtQuestionInfo questionInfo = questionMapstruct.questionInfoMapStruct(item);
            questionInfo.setId(IdUtil.fastUUID());
            // 插入之前先获取主表 id
            questionInfo.setObjectID(question.getId());
            //!
            questionInfos.add(questionInfo);
            // questionInfoMapper.insert(questionInfo);

            //! 是否为单多选类型的问卷
            if (item.getQueType() != 3){
                item.getInputValueArray().forEach((option) -> {
                    //* 插入问卷调查 选项表
                    BtQuestionOption questionOption = new BtQuestionOption();
                    questionOption.setId(IdUtil.fastUUID());
                    // 插入之前先获取内容表 id
                    questionOption.setObjectID(questionInfo.getId());
                    questionOption.setOptionValue(option);
                    //!
                    questionOptions.add(questionOption);
                    // questionOptionMapper.insert(questionOption);
                });
            }
        });
        //! 执行批量插入 sql 语句
        questionInfoMapper.insertQuestionInfo(questionInfos);
        if (questionOptions.size() > 0){
            questionOptionMapper.insertQuestionOption(questionOptions);
        }

        return isInsertQuestionSuccess;
    }

    /**
     * 更新问卷
     * @param
     * @return 更新结果
     */
    @Transactional
    @Override
    public int updateQuestion(BtQuestionDTO questionDTO) {
        int isUpdateQuestionSuccess = 0;

        if (questionDTO.getQuestions() == null){
            // 执行对象转换：
            BtQuestion question = questionMapstruct.questionMapStruct(questionDTO);


            isUpdateQuestionSuccess = questionMapper.updateById(question);
        }else {
            // 执行对象转换：
            BtQuestion question = questionMapstruct.questionMapStruct(questionDTO);
            //* 根据 id 更新主表
            isUpdateQuestionSuccess = questionMapper.updateById(question);

            //! 根据内容表字段 ObjectID 删除内容表
            QueryWrapper<BtQuestionInfo> infoWrapper = new QueryWrapper<>();
            infoWrapper.eq("ObjectID",question.getId());
            questionInfoMapper.delete(infoWrapper);

            //* 创建新增数据的 info 表集合
            List<BtQuestionInfo> addInfoList = new ArrayList<>();
            //* 创建新增数据的 option 表集合
            List<BtQuestionOption> addOptionList = new ArrayList<>();
            //? 创建删除数据的 option 表集合
            List<BtQuestionOption> delOptionList = new ArrayList<>();

            //* 循环内容表 dto
            questionDTO.getQuestions().forEach(infoDTO -> {
                BtQuestionInfo questionInfo = questionMapstruct.questionInfoMapStruct(infoDTO);
                questionInfo.setId(IdUtil.fastUUID());
                //! 根据内容表字段 ObjectID 新增数据
                questionInfo.setObjectID(question.getId());
                addInfoList.add(questionInfo);
                // questionInfoMapper.insert(questionInfo);

                //? 根据选项表表字段 ObjectID 删除选项表
                BtQuestionOption delQuestionOption = new BtQuestionOption();
                delQuestionOption.setObjectID(infoDTO.getId());
                delOptionList.add(delQuestionOption);

                // QueryWrapper<BtQuestionOption> optionWrapper = new QueryWrapper<>();
                // optionWrapper.eq("ObjectID",infoDTO.getId());
                // questionOptionMapper.delete(optionWrapper);

                //判断是否为单多选题
                if (infoDTO.getQueType() != 3){
                    infoDTO.getInputValueArray().forEach(option -> {
                        //? 根据选项表表字段 ObjectID 新增数据
                        BtQuestionOption addQuestionOption = new BtQuestionOption();
                        addQuestionOption.setId(IdUtil.fastUUID());
                        addQuestionOption.setObjectID(questionInfo.getId());
                        addQuestionOption.setOptionValue(option);
                        addOptionList.add(addQuestionOption);
                        // questionOptionMapper.insert(questionOption);
                    });
                }
            });

            //! 执行 info 表批量插入语句
            questionInfoMapper.insertQuestionInfo(addInfoList);
            //! 执行 option 表批量删除语句
            questionOptionMapper.delQuestionOption(delOptionList);
            //! 执行 option 表批量插入语句
            if (addOptionList.size() > 0){
                questionOptionMapper.insertQuestionOption(addOptionList);
            }

        }
        return isUpdateQuestionSuccess;
    }

    /**
     * 查询问卷详情
     *
     * @param id 问卷 id
     * @return
     */
    @Override
    public BtQuestionDTO fetchQuestion(String id) {
<<<<<<< HEAD
        BtQuestionDTO questionDTO = questionMapper.fetchQuestion(id);
=======
        //! 查询问卷主表
        BtQuestion question = questionMapper.selectById(id);
        //* 执行对象转换：
        BtQuestionDTO questionDTO = questionMapstruct.questionDTOMapStruct(question);


        //! 查询内容表
        QueryWrapper<BtQuestionInfo> questionInfoWrapper = new QueryWrapper<>();
        questionInfoWrapper.eq("ObjectID",id);
        List<BtQuestionInfo> questionInfoList = questionInfoMapper.selectList(questionInfoWrapper);
        //* 循环执行对象转换,并且重新添加到集合中：
        List<BtQuestionInfoDTO> questionInfoDTOList = new ArrayList<>();
        questionInfoList.forEach(info -> {
            BtQuestionInfoDTO questionInfoDTO = questionMapstruct.questionInfoDTOMapStruct(info);
            questionInfoDTOList.add(questionInfoDTO);
        });

        //! 查询选项表
        //* 循环内容表 dto 列表
        // 创建 option 表的查询集合
        List<BtQuestionOption> selectOptionList = new ArrayList<>();
        questionInfoDTOList.forEach(item -> {
            BtQuestionOption selectQuestionOption = new BtQuestionOption();
            selectQuestionOption.setObjectID(item.getId());
            //!
            selectOptionList.add(selectQuestionOption);
        });
        //! 执行 option 的批量查询语句
        List<BtQuestionOption> questionOptions = questionOptionMapper.selectQuestionOption(selectOptionList);


        questionInfoDTOList.forEach(item -> {
            //* 根据当前循环的内容表的 id 查询到的选项表,循环添加到 list 集合中
            List<BtQuestionOption> optionList = new ArrayList<>();
            //! stream().filter 过滤
            optionList = questionOptions.stream().filter(option -> {
                return option.getObjectID().equals(item.getId());
            }).collect(Collectors.toList());

            //* 添加到 String 集合中
            List<String> optionValues = new ArrayList<>();
            //* 循环过滤出来的选项表，并添加到 String 集合中
            optionList.forEach(option -> {
                optionValues.add(option.getOptionValue());
            });
            //* 再把当前的 选项表集合 添加到当前循环的 内容表 dto 中
            item.setInputValueArray(optionValues);
        });
>>>>>>> 3ff213d12ff111d24fe4101bd4c1e1cddecc6f9b

        return questionDTO;
    }

    /**
     * 关闭问卷
     *
     * @param id 问卷 id
     * @return
     */
    @Transactional
    @Override
    public int updateCloseQuestion(String id) {
        BtQuestion question = new BtQuestion();
        question.setId(id);
        question.setClose(0);


        int isCloseSuccess = questionMapper.updateById(question);

        return isCloseSuccess;
    }

    /**
     * 删除问卷
     *
     * @param id 问卷 id
     * @return
     */
    @Transactional
    @Override
    public int deleteQuestion(String id) {

        int isDelSuccess = questionMapper.deleteById(id);

        return isDelSuccess;
    }

    /**
     * 统计问卷
     * @param
     * @return 查询结果数
     */
    @Override
    public Map<String,Map<String,Integer>> statisticalQuestion(String id) {
<<<<<<< HEAD

        //! 根据主表 id 查询问卷详情
        BtQuestionDTO questionDTO = questionMapper.fetchQuestion(id);

=======
        //* 1、通过主表 id 查询 info 表的问题题目 id
        QueryWrapper<BtQuestionInfo> questionInfoWrapper = new QueryWrapper<>();
        questionInfoWrapper.eq("ObjectID",id);
        List<BtQuestionInfo> questionInfos = questionInfoMapper.selectList(questionInfoWrapper);
        //* 2、对问题题目进行分类的集合
        List<String> infoIDList = new ArrayList<>();
        //* 3、根据问题题目 id 分别去查询 选项表
        List<BtQuestionOption> selectQueOption = new ArrayList<>();
        questionInfos.forEach(item -> {
            infoIDList.add(item.getId());
            BtQuestionOption questionOption = new BtQuestionOption();
            questionOption.setObjectID(item.getId());
            selectQueOption.add(questionOption);
        });
        //! 执行批量查询语句
        List<BtQuestionOption> questionOptions = questionOptionMapper.selectQuestionOption(selectQueOption);
        //* 4、对选项表的 ObjectId 和 infoIDList 集合中的 info表id 进行匹配过滤
        /**
         * Map 集合：根据 问题题目 的进行分类
         *! key：问题题目的 id（infoID）
         *! value：每个问题题目下面的选项
         */
        Map<String,List<BtQuestionOption>> map = new HashMap<>();
        infoIDList.forEach(infoId -> {
            List<BtQuestionOption> questionOptionList = new ArrayList<>();
            questionOptions.forEach(option -> {
                if (option.getObjectID().equals(infoId)){
                    questionOptionList.add(option);
                }
            });
            map.put(infoId,questionOptionList);
        });

        //* 5、根据主表 id 查询 answer 表的数据
        QueryWrapper<BtQuestionAnswer> questionAnswerWrapper = new QueryWrapper<>();
        questionAnswerWrapper.eq("QuestionID",id);
        List<BtQuestionAnswer> allAnswers = questionAnswerMapper.selectList(questionAnswerWrapper);
>>>>>>> 3ff213d12ff111d24fe4101bd4c1e1cddecc6f9b

        //* 6、对查询出来的 answer 表数据进行筛选分类
        /**
         *! 最终返回给前端的 map
         * {
         *     infoId1:{
         *         id1-optionValue1:count,
         *         id1-optionValue2:count
         *         total:count,  //总人数
         *         max:count     //最多的选项
         *     }
         *     infoId2:{
         *         id2-optionValue1:count,
         *         id2-optionValue2:count
         *         total:count,  //总人数
         *         max:count     //最多的选项
         *     }
         *
         * }
         */
<<<<<<< HEAD
        //* 存储 infoId 的集合
        List<String> infoIds = new ArrayList<>();

        questionDTO.getQuestions().forEach(info -> {
            infoIds.add(info.getId());
        });
        //! 根据选项表的 ObjectId 查询 ID
        List<BtQuestionOption> questionOptions = questionOptionMapper.selectQuestionOption(infoIds);
        //! 统计人数
        List<BtQuestionAnswer> questionAnswerS = questionAnswerMapper.statisticalQuestion(questionOptions);


        Map<String,Map<String,Integer>> toFrontMap = new HashMap();
        questionDTO.getQuestions().forEach(info -> {
            int total = 0;
            int max = 0;
            Map<String,Integer> infoMap = new HashMap();

            for (int i = 0;i < questionAnswerS.size();i++){

                //* 判断当 infoid 相等时，统计人的总数
                if (info.getId() .equals(questionAnswerS.get(i).getInfoId()) ){
                    total += 1;
                }
            }
            //* 根据 infoID 筛选 questionAnswerS 集合
            List<BtQuestionAnswer> collect = questionAnswerS.stream().filter(item -> {
                return info.getId().equals(item.getInfoId());
            }).collect(Collectors.toList());


            for (int i = 0;i < questionOptions.size();i++){
                int count = 0;
                for (int j = 0;j < collect.size();j++){
                    if(collect.get(j).getOptionID().equals(questionOptions.get(i).getId())){
                        count ++;
                        infoMap.put(questionOptions.get(i).getOptionValue(),count);
                        if (max < count){
                            max = count;
                        }
                    }

                }

            }



            infoMap.put("total",total);
            infoMap.put("max",max);


            toFrontMap.put(info.getId(),infoMap);
        });
=======
        Map<String,Map<String,Integer>> toFrontMap = new HashMap();
        for (Map.Entry<String, List<BtQuestionOption>> m : map.entrySet()) {
            Map<String,Integer> infoMap = new HashMap();
            //! 过滤出 info 一致的 answer 数据
            List<BtQuestionAnswer> answerCollect = allAnswers.stream().filter(item -> {
                if (item.getInfoId().equals(m.getKey())) {
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
            // 循环 map 的 value
            int total = 0;
            int max = 0;
            for (int j = 0;j < m.getValue().size();j++) {
                int count = 0;
                for (int i = 0; i < answerCollect.size(); i++) {
                    if (answerCollect.get(i).getOptionID().equals(m.getValue().get(j).getId())) {
                        count = count + 1;
                    }
                }
                if (max < count){
                    max = count;
                }
                total = total + count;

                infoMap.put(m.getValue().get(j).getOptionValue(), count);

            }
            infoMap.put("total",total);
            infoMap.put("max",max);
            toFrontMap.put(m.getKey(),infoMap);
        }
>>>>>>> 3ff213d12ff111d24fe4101bd4c1e1cddecc6f9b


        return toFrontMap;
    }


    // * =================================================基础增删改查END============================================== *
}



//        //! 查询问卷主表
//        BtQuestion question = questionMapper.selectById(id);
//        //* 执行对象转换：
//        BtQuestionDTO questionDTO = questionMapstruct.questionDTOMapStruct(question);
//
//
//        //! 查询内容表
//        QueryWrapper<BtQuestionInfo> questionInfoWrapper = new QueryWrapper<>();
//        questionInfoWrapper.eq("ObjectID",id);
//        List<BtQuestionInfo> questionInfoList = questionInfoMapper.selectList(questionInfoWrapper);
//        //* 循环执行对象转换,并且重新添加到集合中：
//        List<BtQuestionInfoDTO> questionInfoDTOList = new ArrayList<>();
//        questionInfoList.forEach(info -> {
//            BtQuestionInfoDTO questionInfoDTO = questionMapstruct.questionInfoDTOMapStruct(info);
//            questionInfoDTOList.add(questionInfoDTO);
//        });
//
//        //! 查询选项表
//        //* 循环内容表 dto 列表
//        // 创建 option 表的查询集合
//        List<BtQuestionOption> selectOptionList = new ArrayList<>();
//        questionInfoDTOList.forEach(item -> {
//            BtQuestionOption selectQuestionOption = new BtQuestionOption();
//            selectQuestionOption.setObjectID(item.getId());
//            //!
//            selectOptionList.add(selectQuestionOption);
//        });
//        //! 执行 option 的批量查询语句
//        List<BtQuestionOption> questionOptions = questionOptionMapper.selectQuestionOption(selectOptionList);
//
//
//        questionInfoDTOList.forEach(item -> {
//            //* 根据当前循环的内容表的 id 查询到的选项表,循环添加到 list 集合中
//            List<BtQuestionOption> optionList = new ArrayList<>();
//            //! stream().filter 过滤
//            optionList = questionOptions.stream().filter(option -> {
//                return option.getObjectID().equals(item.getId());
//            }).collect(Collectors.toList());
//
//            //* 添加到 String 集合中
//            List<String> optionValues = new ArrayList<>();
//            //* 循环过滤出来的选项表，并添加到 String 集合中
//            optionList.forEach(option -> {
//                optionValues.add(option.getOptionValue());
//            });
//            //* 再把当前的 选项表集合 添加到当前循环的 内容表 dto 中
//            item.setInputValueArray(optionValues);
//        });
//
//        //* 再把内容表 dto 设置到主表 dto 对象中
//        questionDTO.setQuestions(questionInfoDTOList);